package com.framework.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.framework.dao.FlowAccountDao;
import com.framework.entity.flow.FlowAccount;
import com.framework.entity.flow.FlowActiv;
import com.framework.entity.flow.FlowTask;
import com.framework.entity.flow.FlowVipCashBack;
import com.framework.entity.sys.SysAgent;
import com.framework.entity.sys.SysAgentInfo;
import com.framework.entity.tran.TranBenefitDay;
import com.framework.exception.RRException;
import com.framework.exception.menu.RespCode;
import com.framework.service.*;
import com.framework.utils.DateUtils;
import com.framework.utils.PackUtils;
import com.framework.utils.string.StringUtil;
import com.framework.utils.verified.MathUtils;
import com.framework.validator.Assert;
import com.framework.view.AssView;
import com.framework.view.DataBean;
import com.framework.view.FlowAccountView;
import com.framework.view.NameBean;
import com.framework.yhbEntity.view.CusTranView;
import org.apache.commons.collections.map.HashedMap;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author wq
 */
@Service("flowAccountService")
public class FlowAccountServiceImpl extends ServiceImpl<FlowAccountDao, FlowAccount> implements FlowAccountService {

    @Autowired
    private AgentService agentService;
    @Autowired
    private AgentInfoService agentInfoService;

    @Autowired
    private FlowActivService flowActivService;
    @Autowired
    private FlowTaskService flowTaskService;


    @Override
    public List<FlowAccount> queryFlowAccountList(String token, FlowAccount flowAccount, Integer pageNo) {
        if (pageNo == null) {
            throw new RRException(RespCode.NOT_PARAM_ERROR);
        }
        pageNo = pageNo * 10;
        SysAgent agent = agentService.queryAgentByToken(token);
        Long agentId = agent.getAgentId();
        flowAccount.setAgentId(agentId);
        return baseMapper.queryFlowAccountList(flowAccount, pageNo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertFlowAccount(FlowAccount flowAccount) {
        Assert.isNull(flowAccount, "参数不能为空");
        try {
            FlowAccount account = queryByBelId(flowAccount.getBelId());
            if(account==null){
                flowAccount.setCreateTime(new Date());
                baseMapper.insert(flowAccount);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RRException("9000","流水记录添加异常,请勿频繁点击") ;
        }

    }

    @Override
    public Map<String, Object> queryMonthProfitSumList(String token) {
        Map<String, Object> map = new HashedMap();
        SysAgent agent = agentService.queryAgentByToken(token);
        Long agentId = agent.getAgentId();
        //本年的前6个月
        String startMonth = StringUtil.getLast12Months(5);
        //本月
        String endMonth = StringUtil.getLast12Months(0);
        //查询近期6个月收益
        List<Map<String, Object>> list = baseMapper.queryMonthProfitSumList(agentId, startMonth, endMonth);
        //查询总收益
        SysAgentInfo agentInfo = agentInfoService.getAgentInfoById(agentId);
        map.put("monthList", list);
        map.put("totalAmount", agentInfo.getTotalAmount());
        return map;
    }

    @Override
    public BigDecimal queryOtherAmount(Long agentId) {
        return baseMapper.queryOtherAmount(agentId);
    }

    @Override
    public List<FlowAccountView> queryOtherAmountList(String token) {
        SysAgent agent = agentService.queryAgentByToken(token);
        Long agentId = agent.getAgentId();
        List<FlowAccountView> list = baseMapper.queryOtherAmountList(agentId);
        for (int i = 0; i < list.size(); i++) {
            String id = list.get(i).getBelId();
            Integer state = list.get(i).getAccountType();
            String sn = baseMapper.queryOtherSn(id, state);
            list.get(i).setSn(sn);
        }
        return list;
    }

    @Override
    public List<Map<String, Object>> queryFlowAccountTable(String token, Integer type, String startDate, String endDate) {
        List<Map<String, Object>> result = new ArrayList<>();
        SysAgent sysAgent = agentService.queryAgentByToken(token);
        Map<String, Object> resultMap = new HashMap<>(2);

        BigDecimal totalAmount = new BigDecimal("0.00");
        BigDecimal totalAmount2 = new BigDecimal("0.00");

        if ((startDate == null || "".equals(startDate)) && (endDate == null || "".equals(endDate))) {
            Integer offset1 = type == 1 ? 1 : type == 2 ? 7 : 30;
            Integer offset2 = type == 1 ? 2 : type == 2 ? 14 : 60;
            Date today = DateUtils.stringToDate(DateUtils.format(new Date(), DateUtils.DATE_PATTERN), DateUtils.DATE_PATTERN);
            Date one = DateUtils.addDateDays(today, -offset1);
            Date two = DateUtils.addDateDays(today, -offset2);

            Map<String, Object> map = baseMapper.queryAgentAccountInfo(sysAgent.getAgentId(), one, today);

            String time = DateUtils.dateToString(one, today, "yyyy/MM/dd", "-", 5);
            totalAmount = totalAmount.add(new BigDecimal(map.get("selfAmount").toString()));
            totalAmount = totalAmount.add(new BigDecimal(map.get("teamAmount").toString()));
            totalAmount = totalAmount.add(new BigDecimal(map.get("activAmount").toString()));
            totalAmount = totalAmount.add(new BigDecimal(map.get("otherAmount").toString()));
            map.put("selfName", "自营");
            map.put("teamName", "推广");
            map.put("activName", "激活");
            map.put("otherName", "其他");
            resultMap.put("time", time);
            resultMap.put("data", map);
            resultMap.put("totalAmount", MathUtils.formatToNumber(totalAmount));
            result.add(resultMap);

            Map<String, Object> resultMap2 = new HashMap<>(2);

            Map<String, Object> map2 = baseMapper.queryAgentAccountInfo(sysAgent.getAgentId(), two, one);
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("selfAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("teamAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("activAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("otherAmount").toString()));

            String time2 = DateUtils.dateToString(two, one, "yyyy/MM/dd", "-", 5);

            map2.put("selfName", "自营");
            map2.put("teamName", "推广");
            map2.put("activName", "激活");
            map2.put("otherName", "其他");
            resultMap2.put("time", time2);
            resultMap2.put("data", map2);
            resultMap2.put("totalAmount", MathUtils.formatToNumber(totalAmount2));
            result.add(resultMap2);

        } else {
            Date start = DateUtils.stringToDate(startDate, DateUtils.DATE_PATTERN);
            Date end = DateUtils.stringToDate(endDate, DateUtils.DATE_PATTERN);

            Map<String, Object> map2 = baseMapper.queryAgentAccountInfo(sysAgent.getAgentId(), start, end);
            String time2 = DateUtils.dateToString(start, end, "yyyy/MM/dd", "-", 5);

            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("selfAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("teamAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("activAmount").toString()));
            totalAmount2 = totalAmount2.add(new BigDecimal(map2.get("otherAmount").toString()));
            map2.put("selfName", "自营");
            map2.put("teamName", "推广");
            map2.put("activName", "激活");
            map2.put("otherName", "其他");
            resultMap.put("time", time2);
            resultMap.put("data", map2);
            resultMap.put("totalAmount", MathUtils.formatToNumber(totalAmount2));
            result.add(resultMap);
        }
        return result;
    }

    @Override
    public Map<String, Object> queryIncomeInfo(String token, Integer pageNo, Integer incomeType, Integer dateType, String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>(3);

        Map<String, Object> map = queryIncomeList(token, pageNo, dateType, incomeType, startDate, endDate);

        Map<String, Object> map2 = queryIncomeAndExpend(token, dateType, startDate, endDate);

        result.putAll(map);
        result.putAll(map2);

        return result;
    }

    @Override
    public Map<String, Object> queryIncomeAndExpend(String token, Integer dateType, String startDate, String endDate) {

        SysAgent agent = agentService.queryAgentByToken(token);
        List<FlowAccount> expenditures = selectList(new EntityWrapper<FlowAccount>().eq("agent_id", agent.getAgentId())
                .eq("support_type", 1)
                .eq("account_type", 2)
                .like(dateType == 1, "create_time", DateUtils.format(new Date(), "yyyy-MM"))
                .between(dateType == 3, "create_time", startDate, endDate)

        );

        List<FlowTask> takeList = flowTaskService.selectList(new EntityWrapper<FlowTask>()
                .eq("task_state", "success")
                .eq("agent_id", agent.getAgentId())
                .like(dateType == 1, "create_time", DateUtils.format(new Date(), "yyyy-MM"))
                .between(dateType == 3, "create_time", startDate, endDate));

        BigDecimal takeAmounts = takeList.stream().map(FlowTask::getTakeAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal expendTotal = expenditures.stream().map(FlowAccount::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

        expendTotal = expendTotal.add(takeAmounts);

        List<FlowAccount> incomes = selectList(new EntityWrapper<FlowAccount>().eq("agent_id", agent.getAgentId())
                .eq("support_type", 2)
                .like(dateType == 1, "create_time", DateUtils.format(new Date(), "yyyy-MM"))
                .between(dateType == 3, "create_time", startDate, endDate)
        );

        BigDecimal incomeTotal = incomes.stream().map(FlowAccount::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        Map<String, Object> result = new HashMap<>(2);
        result.put("expendTotal", expendTotal);
        result.put("incomeTotal", incomeTotal);
        return result;
    }

    @Override
    public Map<String, Object> queryIncomeList(String token, Integer pageNo, Integer dateType, Integer incomeType, String startDate, String endDate) {
        if (pageNo == null || pageNo.intValue() == 0) {
            throw new RRException("9000", "页码不能为空或者0");
        }
        if (incomeType == null || incomeType.intValue() == 0) {
            throw new RRException("9000", "收益类型不能为空或者0");
        }
        if (dateType == null || dateType.intValue() == 0) {
            throw new RRException("9000", "时间类型不能为空或者0");
        }
        //3 为时间筛选
        if (dateType.intValue() == 3) {
            if (startDate == null || endDate == null) {
                throw new RRException("9000", "开始以及结束时间不能为空");
            }
        }
        SysAgent agent = agentService.queryAgentByToken(token);
        Map<String, Object> params = new HashMap<>(7);
        params.put("start", (pageNo - 1) * 10);
        params.put("limit", 10);
        params.put("agentId", agent.getAgentId());
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("dateType", dateType);
        params.put("incomeType", incomeType);
        params.put("deptId", agent.getDeptId());
        List<Map<String, Object>> resultList;

        if (incomeType.intValue() == 3) {
            resultList = flowActivService.queryActivByAgentId(params);
        } else if (incomeType.intValue() == 4) {
            resultList = baseMapper.queryOtherFlowAccountByAgentId(params);
        } else {
            resultList = baseMapper.queryFlowAccountByAgentId(params);
        }
        List<CusTranView> list = PackUtils.packToCusTranView(resultList, "date", "yyyy-MM-dd");

        Map<String, Object> result = new HashMap<>(1);
        result.put("list", list);
        return result;
    }

    @Override
    public List<AssView> queryAssList(String token, Integer pageNo) {
        SysAgent agent = agentService.queryAgentByToken(token);
        if (pageNo == null || pageNo.intValue() == 0) {
            throw new RRException("9000", "页数不能为空或者0");
        }
        List<FlowAccount> accounts = baseMapper.selectPage(
                new RowBounds((pageNo - 1) * 10, 10),
                new EntityWrapper<FlowAccount>()
                        .eq("agent_id", agent.getAgentId())
                        .orderBy("create_time", false));

        AssView view;
        List<AssView> list = new ArrayList<>(accounts.size());
        for (FlowAccount account : accounts) {
            Integer accountType = account.getAccountType();
            view = new AssView();
            DataBean data = new DataBean();
            NameBean name = new NameBean();
            if (accountType.intValue() == 1) {
                view.setType(1);
                view.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));
                data.setAmount(account.getAmount());
                data.setProfit(account.getProfit().toString());
                data.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));

                name.setAmountName("提现通知");
                name.setDateName("提现日期");
                name.setProfitName("");

            } else if (accountType.intValue() == 3) {
                view.setType(2);
                view.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));
                data.setAmount(account.getAmount());
                data.setProfit(account.getProfit().toString());
                data.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));

                name.setAmountName("商户拓展分润");
                name.setDateName("分润日期");
                name.setProfitName("参与分润交易");
            } else if (accountType.intValue() == 4) {
                view.setType(3);
                view.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));
                data.setAmount(account.getAmount());
                data.setProfit(account.getProfit().toString());
                data.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));

                name.setAmountName("团队推广分润");
                name.setDateName("分润日期");
                name.setProfitName("参与分润交易");
            } else if (accountType.intValue() == 5) {
                view.setType(4);
                view.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));
                data.setAmount(account.getAmount());
                data.setDate(DateUtils.format(account.getCreateTime(), DateUtils.DATE_PATTERN));
                FlowActiv flowActiv = flowActivService.selectById(account.getBelId());
                data.setProfit(flowActiv.getSn());

                name.setAmountName("激活返现");
                name.setDateName("激活返现日期");
                name.setProfitName("返现机器");
            }

            view.setDataBean(data);
            view.setNameBean(name);

            list.add(view);
        }

        return list;
    }



    @Override
    public FlowAccount queryByBelId(FlowAccount account) {
        return baseMapper.selectOne(account);
    }
    @Override
    public FlowAccount queryByBelId(String belId) {
        FlowAccount account=new FlowAccount();
        account.setBelId(belId);
        return queryByBelId(account);
    }

    @Override
    public void addFlowAccountAfterBenefit(TranBenefitDay tranBenefitDay) {

        //自营大于0
        if(tranBenefitDay.getSelfAmount().compareTo(new BigDecimal("0.00"))==1){

            FlowAccount account = selectOne(new EntityWrapper<FlowAccount>().eq("bel_id", tranBenefitDay.getBenefitId()).eq("account_type", 3));

            if(account==null){
                account=new FlowAccount();
                account.setCreateTime(new Date());
                account.setSupportType(2);
                account.setAgentId(tranBenefitDay.getAgentId());
                account.setBelId(tranBenefitDay.getBenefitId());
                account.setAmount(tranBenefitDay.getSelfAmount());
                account.setProfit(tranBenefitDay.getSelfTran());
                account.setAccountType(3);
                account.setRemark(tranBenefitDay.getSelfTran().toString());
                insert(account);

            }else {
                account.setAmount(tranBenefitDay.getSelfAmount());
                account.setProfit(tranBenefitDay.getSelfTran());
                account.setAccountType(3);
                account.setRemark(tranBenefitDay.getSelfTran().toString());
                updateById(account);


            }
        }


        //团队大于0
        if(tranBenefitDay.getTeamAmount().compareTo(new BigDecimal("0.00"))==1){

            FlowAccount account = selectOne(new EntityWrapper<FlowAccount>().eq("bel_id", tranBenefitDay.getBenefitId()).eq("account_type", 4));

            if(account==null){
                account=new FlowAccount();
                account.setCreateTime(new Date());
                account.setSupportType(2);
                account.setAgentId(tranBenefitDay.getAgentId());
                account.setBelId(tranBenefitDay.getBenefitId());
                account.setAmount(tranBenefitDay.getTeamAmount());
                account.setProfit(tranBenefitDay.getTeamTran());
                account.setAccountType(4);
                account.setRemark(tranBenefitDay.getTeamTran().toString());
                insert(account);

            }else {
                account.setAmount(tranBenefitDay.getTeamAmount());
                account.setProfit(tranBenefitDay.getTeamTran());
                account.setAccountType(4);
                account.setRemark(tranBenefitDay.getTeamTran().toString());
                updateById(account);

            }


        }
    }

    @Override
    public void addVipCashAccount(FlowVipCashBack flow, int accountType) {
        baseMapper.addFlowVip(flow);

        FlowVipCashBack flowVipCashBack=baseMapper.queryFLowVip(flow.getSn(),flow.getCreateTime());

        FlowAccount flowAccount=new FlowAccount();
        flowAccount.setCreateTime(new Date());
        flowAccount.setSupportType(2);
        flowAccount.setAgentId(flowVipCashBack.getAgentId());
        flowAccount.setBelId(flowVipCashBack.getId().toString());
        flowAccount.setAmount(flowVipCashBack.getMoney());
        flowAccount.setAccountType(8);
        flowAccount.setRemark(flowVipCashBack.getSn());
        insert(flowAccount);

    }
    @Override
    public FlowVipCashBack queryVipBySn(String sn,Date vipTime){
        return baseMapper.queryFLowVipByVipTime(sn,vipTime);
    }

}
